package graph

import (
	"encoding/json"

	"github.com/RocksonZeta/wrap/utils/nutil"
)

type Props map[string]interface{}

func UnmarshalProps(str string) Props {
	var r map[string]interface{}
	json.Unmarshal([]byte(str), &r)
	return r
}
func NewProps() Props {
	return make(map[string]interface{})
}
func NewPropsLen(l int) Props {
	return make(map[string]interface{}, l)
}

func (p Props) Marshal() string {
	bs, _ := json.Marshal(p)
	return string(bs)
}

//CheckNotIn Get props's keys not in keys of param
func (p Props) CheckNotIn(keys []string) []string {
	m := make(map[string]bool, len(keys))
	for _, v := range keys {
		m[v] = true
	}
	var r []string
	for k := range p {
		if !m[k] {
			r = append(r, k)
		}
	}
	return r
}
func (p Props) Pick(keys []string) Props {
	r := NewPropsLen(len(keys))
	for _, k := range keys {
		if v, ok := p[k]; ok {
			r[k] = v
		}
	}
	return r
}
func (p Props) Has(key string) bool {
	_, ok := p[key]
	return ok
}
func (p Props) Remove(key string) {
	delete(p, key)
}
func (p Props) SetName(name string) {
	p["name"] = name
}
func (p Props) GetName() string {
	if from, ok := p["name"]; ok {
		return from.(string)
	}
	return ""
}
func (p Props) SetX(x float64) {
	p["x"] = x
}
func (p Props) GetX() float64 {
	return nutil.ValueOf(p["x"]).AsFloat64()
}
func (p Props) SetY(y float64) {
	p["y"] = y
}
func (p Props) GetY() float64 {
	return nutil.ValueOf(p["y"]).AsFloat64()
}
func (p Props) SetFrom(from int) {
	p["from"] = from
}
func (p Props) GetFrom() int {
	if from, ok := p["from"]; ok {
		return nutil.ValueOf(from).AsInt()
	}
	return 0
}
func (p Props) SetTo(to int) {
	p["to"] = to
}
func (p Props) GetTo() int {
	if to, ok := p["to"]; ok {
		return nutil.ValueOf(to).AsInt()

	}
	return 0
}
func (p Props) SetParent(parent int) {
	p["parent"] = parent
}
func (p Props) GetParent() int {
	if parent, ok := p["parent"]; ok {
		return nutil.ValueOf(parent).AsInt()
	}
	return 0
}
func (p Props) SetStyles(props map[string]interface{}) {
	p["styles"] = props
}
func (p Props) SetStyle(key string, value interface{}) {
	props := p.GetStyles()
	if nil == props {
		props = NewProps()
		p["styles"] = map[string]interface{}(props)
	}
	props[key] = value
}
func (p Props) GetStyles() map[string]interface{} {
	if prop, ok := p["styles"]; ok {
		return prop.(map[string]interface{})
	}
	return nil
}
func (p Props) SetUIs(props []map[string]interface{}) {
	p["uis"] = props
}
func (p Props) SetUI(key string, value interface{}) {
	props := p.GetStyles()
	if nil == props {
		props = NewProps()
		p["uis"] = map[string]interface{}(props)
	}
	props[key] = value
}
func (p Props) GetUIs() []map[string]interface{} {
	if prop, ok := p["uis"]; ok {
		return prop.([]map[string]interface{})
	}
	return nil
}

func (p Props) Extend(a Props) {
	if a == nil {
		return
	}
	for k, v := range a {
		if _, ok := p[k]; !ok {
			p[k] = v
			continue
		}
		av, ok1 := v.(map[string]interface{})
		pv, ok2 := p[k].(map[string]interface{})
		if ok1 && ok2 {
			for k1, v1 := range av {
				if _, ok := pv[k1]; !ok {
					pv[k1] = v1
				}
			}
		}
	}

}
